package com.qqs.socket;

import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.log4j.Logger;

import com.qqs.business.media.PlayMusic;
import com.qqs.eq.StatusPublish;
import com.qqs.util.ConvertUtil;

public final class ProtocolAnalysis {
	static ExecutorService fixedThreadPool = Executors
			.newFixedThreadPool(Runtime.getRuntime().availableProcessors() * 2);
	private static final Logger logger = Logger.getLogger(ProtocolAnalysis.class);
	private static Map<String, String> lightData = new ConcurrentHashMap();
	private static Map<String, String> tempData = new ConcurrentHashMap();
	private static Map<String, String> ledData = new ConcurrentHashMap();
	private static Map<String, Long> sensorData = new ConcurrentHashMap();
	private static Map<String, String> cleanData = new ConcurrentHashMap();
	private static final int xiaobaiRate = 30 * 1000;
	private static final int eemRate = 30 * 1000;

	public final static void dealEnocean(byte[] data) {
		fixedThreadPool.execute(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				if ((data[6] & 0xFF) == 0xD1 && (data[7] & 0xFF) == 0x68) {
					if ((data[8] & 0xFF) == 0x80 && (data[9] & 0xFF) == 0xB0) {// 灯光
						lightStatus(data);
					} else if ((data[8] & 0xFF) == 0x84 && ((data[9] & 0xFF) == 0xB1 || (data[9] & 0xFF) == 0xB0)) {// 温度
						thermostatStatus(data);
					} else if ((data[8] & 0xFF) == 0x82 && (data[9] & 0xFF) == 0xB0) {// LED
						ledStatus(data);
					} else if ((data[8] & 0xFF) == 0x8F && (data[9] & 0xFF) == 0xB1) {// 电能
						eemStatus(data);
					} else if (((data[8] & 0xFF) == 0x8E) && ((data[9] & 0xFF) == 0x81)) {// 门锁
						// lockStatus(data);
					} else if (((data[8] & 0xFF) == 0x8E) && ((data[9] & 0xFF) == 0xC1)) {// 音乐
						// musicStatus(data);
					} else if (((data[8] & 0xFF) == 0x8A) && ((data[9] & 0xFF) == 0xB0)) {// 无线小白
						smallWhiteStatus(data);
					}
				} else if (((data[6] & 0xFF) == 0xA5)) {// CO2传感器、人体传感器等
					// sensorStatus(data);
				} else if ((data[6] & 0xFF) == 0xF6 && ((data[7] & 0xFF) == 0x50 || (data[7] & 0xFF) == 0x70
						|| (data[7] & 0xFF) == 0x10 || (data[7] & 0xFF) == 0x30)) {// 开关
					switchStatus(data);
				}
			}
		});
	}

	public final static void dealWifi(byte[] data) {
		fixedThreadPool.execute(new Runnable() {
			@Override
			public void run() {
				airCleanerStatus(data);
			}
		});
	}

	public final static void dealEnoceanRepeat(byte[] data) {
		fixedThreadPool.execute(new Runnable() {
			@Override
			public void run() {
			}
		});
	}

	public final static void dealWifiRepeat(byte[] data) {
		fixedThreadPool.execute(new Runnable() {
			@Override
			public void run() {
			}
		});
	}

	private static void lightStatus(byte data[]) {
		StringBuffer sb = new StringBuffer();
		int ll = data.length;
		byte[] bs = new byte[4];
		bs[0] = data[ll - 13];
		bs[1] = data[ll - 12];
		bs[2] = data[ll - 11];
		bs[3] = data[ll - 10];
		String chipid = ConvertUtil.Byte2HexString2(bs).trim();
		sb.append(chipid);
		int h = data.hashCode();
		Map<String, String> shuxingmap = new HashMap<String, String>();
		String operate = "other";
		if ((data[10] & 0xFF) == 0x10) {
			operate = "controller";
		} else if ((data[10] & 0xFF) == 0x20) {
			operate = "switch";
		} else if ((data[10] & 0xFF) == 0x30) {
			operate = "sensor";
		} else if ((data[10] & 0xFF) == 0x40) {
			operate = "gateway";
		} else if ((data[10] & 0xFF) == 0x50) {
			operate = "timer";
		}
		shuxingmap.put("type", "light");
		shuxingmap.put("operate", operate);
		shuxingmap.put("chipid", chipid);
		SimpleDateFormat DateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		shuxingmap.put("time", DateFormat.format(new Date()));
		for (int i = 15; i < ll - 13; i++) {
			byte b = data[i];
			String node = String.valueOf((b & 0xF0) >> 4);
			shuxingmap.put("n-" + node + "1", (b & 0x01) > 0 ? "on" : "off");
			shuxingmap.put("n-" + node + "2", (b & 0x02) > 0 ? "on" : "off");
			shuxingmap.put("n-" + node + "3", (b & 0x04) > 0 ? "on" : "off");
			shuxingmap.put("n-" + node + "4", (b & 0x08) > 0 ? "on" : "off");
			sb.append(node);
			sb.append((b & 0x01));
			sb.append((b & 0x02));
			sb.append((b & 0x04));
			sb.append((b & 0x08));
		}
		if (!sb.toString().equals(lightData.get(chipid))) {
			lightData.put(chipid, sb.toString());
			StatusPublish.light(chipid, shuxingmap);
		}
	}

	/**
	 * 温控器状态
	 * 
	 * @param data
	 * @return
	 */
	private static void thermostatStatus(byte data[]) {
		int l = data[2] & 0xFF;
		byte[] bs = new byte[4];
		bs[0] = data[l + 1];
		bs[1] = data[l + 2];
		bs[2] = data[l + 3];
		bs[3] = data[l + 4];
		StringBuffer sb = new StringBuffer();
		String chipid = ConvertUtil.Byte2HexString2(bs).trim();
		sb.append(chipid);
		if ((data[9] & 0xFF) == 0xB0) {
			long setTemp = (long) (((data[15] & 0xFF) * 256 + (data[16] & 0xFF)) / 10.0);
			long currentTemp = (long) (((data[17] & 0xFF - 0x80) * 256 + (data[18] & 0xFF)) / 10.0);
			if ((data[17] & 0x80) == 0) {// 负
				currentTemp = currentTemp * -1;
			}
			byte b = data[19];
			int wind = (b & 0x38) >> 3;
			String windStr = "";
			if (wind == 0) {
				windStr = "auto";
			} else if (wind == 1) {
				windStr = "low";
			} else if (wind == 2) {
				windStr = "mid";
			} else if (wind == 3) {
				windStr = "high";
			}
			int mode = (b & 0x07);
			String modeStr = "";
			if (mode == 0) {
				modeStr = "auto";
			} else if (mode == 1) {
				modeStr = "cold";
			} else if (mode == 2) {
				modeStr = "hot";
			} else if (mode == 3) {
				modeStr = "wind";
			}
			Map<String, String> shuxingmap = new HashMap<String, String>();
			shuxingmap.put("type", "temp");
			shuxingmap.put("onoff", (b & 0x80) > 0 ? "on" : "off");
			shuxingmap.put("wind", windStr);
			shuxingmap.put("mode", modeStr);
			shuxingmap.put("setTemp", String.valueOf(Math.round(setTemp)));
			shuxingmap.put("currentTemp", String.valueOf(Math.round(currentTemp)));
			sb.append((b & 0x80));
			sb.append(wind);
			sb.append(mode);
			sb.append(setTemp);
			sb.append(currentTemp);
			SimpleDateFormat DateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			shuxingmap.put("time", DateFormat.format(new Date()));
			if (!sb.toString().equals(tempData.get(chipid))) {
				tempData.put(chipid, sb.toString());
				StatusPublish.temp(chipid, shuxingmap);
			}
		} else if ((data[9] & 0xFF) == 0xB1) {// B1数据
			long setTemp = (long) (((data[10] & 0xFF) * 256 + (data[11] & 0xFF)) / 10.0);
			int setHumidity = data[12] & 0xFF;
			int currentHumidity = data[15] & 0xFF;
			long currentTemp = (long) (((data[13] & 0xFF - 0x80) * 256 + (data[14] & 0xFF)) / 10.0);
			if ((data[13] & 0x80) == 0) {// 负
				currentTemp = currentTemp * -1;
			}
			boolean onoff = (data[16] & 0xFF) == 0xFF;
			int wind = data[17] & 0xFF;
			String windStr = "";
			if (wind == 0) {
				windStr = "auto";
			} else if (wind == 1) {
				windStr = "low";
			} else if (wind == 2) {
				windStr = "mid";
			} else if (wind == 3) {
				windStr = "high";
			}
			int mode = data[18] & 0xFF;
			String modeStr = "";
			if (mode == 0) {
				modeStr = "auto";
			} else if (mode == 1) {
				modeStr = "cold";
			} else if (mode == 2) {
				modeStr = "hot";
			} else if (mode == 3) {
				modeStr = "wind";
			}
			Map<String, String> shuxingmap = new HashMap<String, String>();
			shuxingmap.put("type", "temp");
			shuxingmap.put("chipid", chipid);
			shuxingmap.put("switch", (onoff ? "on" : "off"));
			shuxingmap.put("wind", windStr);
			shuxingmap.put("mode", modeStr);
			shuxingmap.put("setTemp", String.valueOf(Math.round(setTemp)));
			shuxingmap.put("currentTemp", String.valueOf(Math.round(currentTemp)));
			shuxingmap.put("currentHumidity", String.valueOf(currentHumidity));
			SimpleDateFormat DateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			shuxingmap.put("time", DateFormat.format(new Date()));
			sb.append(onoff);
			sb.append(wind);
			sb.append(mode);
			sb.append(setTemp);
			sb.append(currentTemp);
			sb.append(currentHumidity);
			if (!sb.toString().equals(tempData.get(chipid))) {
				tempData.put(chipid, sb.toString());
				StatusPublish.temp(chipid, shuxingmap);
			}
		}

	}

	/**
	 * LED
	 * 
	 * @param data
	 * @return
	 */
	private static void ledStatus(byte data[]) {
		int l = data[2] & 0xFF;
		byte[] bs = new byte[4];
		bs[0] = data[l + 1];
		bs[1] = data[l + 2];
		bs[2] = data[l + 3];
		bs[3] = data[l + 4];
		StringBuffer sb = new StringBuffer();
		String chipid = ConvertUtil.Byte2HexString(bs).trim();
		sb.append(chipid);
		int ndata_B = (data[16] & 0xFF) * 255 / 100;
		int ndata_G = (data[17] & 0xFF) * 255 / 100;
		int ndata_R = (data[18] & 0xFF) * 255 / 100;
		Map<String, String> shuxingmap = new HashMap<String, String>();
		shuxingmap.put("type", "led");
		shuxingmap.put("R", String.valueOf(ndata_R));
		shuxingmap.put("G", String.valueOf(ndata_G));
		shuxingmap.put("B", String.valueOf(ndata_B));
		sb.append(ndata_B);
		sb.append(ndata_G);
		sb.append(ndata_R);
		SimpleDateFormat DateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		shuxingmap.put("time", DateFormat.format(new Date()));
		if (!sb.toString().equals(ledData.get(chipid))) {
			ledData.put(chipid, sb.toString());
			StatusPublish.led(chipid, shuxingmap);
		}
	}

	private static void smallWhiteStatus(byte data[]) {
		if (data.length < 24)
			return;
		byte[] bs = new byte[4];
		bs[0] = data[21];
		bs[1] = data[22];
		bs[2] = data[23];
		bs[3] = data[24];
		StringBuffer sb = new StringBuffer();
		String chipid = ConvertUtil.Byte2HexString2(bs).trim();
		sb.append(chipid);
		int co2 = 0;
		co2 = Integer.parseInt(String.valueOf(data[8] & 0xFF)) * 10;
		Map<String, String> shuxingmap = new HashMap<String, String>();
		shuxingmap.put("types", "xiaobai");
		double temp;
		int humidity, pm, nH, nL;
		String voc = "";
		if ((data[10] & 0xFF) == 0xA0) {// 温度
			String sign = "";
			if ((data[11] & 0xFF) == 0x00)
				sign = "-";
			nH = (data[12] & 0xFF) * 16 * 16;
			nL = (data[13] & 0xFF);
			temp = (nH + nL) / 10.0;
			int t = (int) Math.round(temp);
			shuxingmap.put("temp", String.valueOf(t));
			sb.append(t);
		}
		if ((data[14] & 0xFF) == 0xA1) {// 湿度
			humidity = Integer.parseInt(String.valueOf(data[15] & 0xFF));
			shuxingmap.put("humidity", String.valueOf(humidity) + "%");
			sb.append(humidity);
		}
		if ((data[16] & 0xFF) == 0xA7) {
			nH = (data[17] & 0xFF) * 16 * 16;
			nL = (data[18] & 0xFF);
			pm = nH + nL;
			shuxingmap.put("pm", String.valueOf(pm));
			sb.append(pm);
		}
		if ((data[19] & 0xFF) == 0xA9) {
			if ((data[20] & 0xFF) == 0x00) {
				voc = "优";
			} else if ((data[20] & 0xFF) == 0x01) {
				voc = "轻度";
			} else if ((data[20] & 0xFF) == 0x02) {
				voc = "中度";
			} else if ((data[20] & 0xFF) == 0x03) {
				voc = "重度";
			}
			shuxingmap.put("voc", voc);
			sb.append(voc);
		}
		Long time = sensorData.get(sb.toString());
		long l = System.currentTimeMillis();
		if (time == null || l - time > xiaobaiRate) {
			sensorData.put(sb.toString(), l);
			StatusPublish.sensor(chipid, shuxingmap);
		}
	}

	private static void airCleanerStatus(byte data[]) {
		int size = data.length;
		StringBuffer sb = new StringBuffer();
		if ((data[2] & 0xFF) + 2 >= size) {
			byte[] bs = new byte[4];
			bs[0] = data[3];
			bs[1] = data[4];
			bs[2] = data[5];
			bs[3] = data[6];
			String chipid = ConvertUtil.Byte2HexString2(bs).trim();
			sb.append(chipid);
			Map<String, String> shuxingmap = new HashMap();
			shuxingmap.put("types", "clean");
			double temp;
			int humidity, pm, nH, nL;
			String voc = "", wind = "";
			if ((data[9] & 0xFF) == 0xA0 || (data[9] & 0xFF) == 0xAA) {// 温度
				String sign = "";
				if ((data[10] & 0xFF) == 0x00)
					sign = "-";
				nH = (data[11] & 0xFF) * 16 * 16;
				nL = (data[12] & 0xFF);
				temp = (nH + nL) / 10.0;
				int t = (int) Math.round(temp);
				shuxingmap.put("temp", String.valueOf(t));
				sb.append(t);
			}
			if ((data[14] & 0xFF) == 0xA1 || (data[14] & 0xFF) == 0xAB) {// 湿度
				humidity = Integer.parseInt(String.valueOf(data[15] & 0xFF));
				shuxingmap.put("humidity", String.valueOf(humidity) + "%");
				sb.append(humidity);
			}
			if ((data[17] & 0xFF) == 0xA7 || (data[17] & 0xFF) == 0xAC) {
				nH = (data[18] & 0xFF) * 16 * 16;
				nL = (data[19] & 0xFF);
				pm = nH + nL;
				shuxingmap.put("pm", String.valueOf(pm));
				sb.append(pm);
			}
			if ((data[21] & 0xFF) == 0xA9 || (data[21] & 0xFF) == 0xAD) {
				if ((data[22] & 0xFF) == 0x00) {
					voc = "优";
				} else if ((data[22] & 0xFF) == 0x01) {
					voc = "轻度";
				} else if ((data[22] & 0xFF) == 0x02) {
					voc = "中度";
				} else if ((data[22] & 0xFF) == 0x03) {
					voc = "重度";
				}
				shuxingmap.put("voc", voc);
				sb.append(voc);
			}
			if ((data[24] & 0xFF) == 0x10) {
				if ((data[25] & 0xFF) == 0x00) {
					wind = "auto";
				} else if ((data[25] & 0xFF) == 0x01) {
					wind = "low";
				} else if ((data[25] & 0xFF) == 0x02) {
					wind = "mid";
				} else if ((data[25] & 0xFF) == 0x03) {
					wind = "high";
				} else if ((data[25] & 0xFF) == 0xFF) {
					wind = "close";
				}
				shuxingmap.put("wind", wind);
				sb.append(wind);
			}
			if (!sb.toString().equals(cleanData.get(chipid))) {
				cleanData.put(chipid, sb.toString());
				StatusPublish.clean(chipid, shuxingmap);
			}
		}

	}

	/**
	 * eem
	 * 
	 * @param data
	 * @return
	 */
	private static void eemStatus(byte data[]) {
		StringBuffer sb = new StringBuffer();
		int l = data[2] & 0xFF;
		byte[] bs = new byte[4];
		bs[0] = data[l + 1];
		bs[1] = data[l + 2];
		bs[2] = data[l + 3];
		bs[3] = data[l + 4];
		String chipid = ConvertUtil.Byte2HexString(bs).trim();
		Byte VoltageHi = data[11];
		Byte VoltageLo = data[12];
		double nH = (VoltageHi & 0xFF) * 16 * 16;
		double nL = (VoltageLo & 0xFF);
		double nVoltage = (nH + nL) / 10.00;// 电压0.1
		Byte CurrentHi = data[13];
		Byte CurrentLo = data[14];
		nH = (CurrentHi & 0xFF) * 16 * 16;
		nL = (CurrentLo & 0xFF);
		double nCurrent = (nH + nL) / 100.00;// 电流0.01
		double Capacity = nVoltage * nCurrent;// 功率0.01W
		// 0.1kWh
		Byte Energy_1 = data[15];
		Byte Energy_2 = data[16];
		Byte Energy_3 = data[17];
		Byte Energy_4 = data[18];
		double Electric = ((Energy_1 & 0xFF) * 16 * 16 * 16 * 16 * 16 * 16 + (Energy_2 & 0xFF) * 16 * 16 * 16 * 16
				+ (Energy_3 & 0xFF) * 16 * 16 + (Energy_4 & 0xFF)) / 10.00;
		int channel = data[10] & 0xFF;
		DecimalFormat df1 = new DecimalFormat("######0.00");
		SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");// 设置日期格式
		Map<String, String> shuxingmap = new HashMap<String, String>();
		shuxingmap.put("type", "eem");
		shuxingmap.put("V" + channel, String.valueOf(Math.round(nVoltage * 10) / 10.0));
		shuxingmap.put("A" + channel, String.valueOf(Math.round(nCurrent * 100) / 100.0));
		shuxingmap.put("W" + channel, String.valueOf(Math.round(Capacity * 100) / 100.0));
		shuxingmap.put("KWH" + channel, String.valueOf(Math.round(Electric * 10) / 10.0));
		shuxingmap.put("time", df.format(new Date()));
		sb.append(String.valueOf(Math.round(nVoltage * 10) / 10.0));
		sb.append(String.valueOf(Math.round(nCurrent * 100) / 100.0));
		sb.append(String.valueOf(Math.round(Capacity * 100) / 100.0));
		sb.append(String.valueOf(Math.round(Electric * 10) / 10.0));
		Long time = sensorData.get(sb.toString());
		long ll = System.currentTimeMillis();
		if (time == null || ll - time > eemRate) {
			sensorData.put(sb.toString(), ll);
			StatusPublish.eem(chipid, shuxingmap);
		}
	}

	private static void switchStatus(byte data[]) {
		byte[] bs = new byte[4];
		bs[0] = data[8];
		bs[1] = data[9];
		bs[2] = data[10];
		bs[3] = data[11];
		String chipid = ConvertUtil.Byte2HexString(bs).trim();
		if ((data[7] & 0xFF) == 0x50) {
			StatusPublish.switchs(chipid, "左上");
		} else if ((data[7] & 0xFF) == 0x70) {
			StatusPublish.switchs(chipid, "左下");
		} else if ((data[7] & 0xFF) == 0x10) {
			StatusPublish.switchs(chipid, "右上");
		} else if ((data[7] & 0xFF) == 0x30) {
			StatusPublish.switchs(chipid, "右下");
		}
	}
}
